using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Media;

namespace Charting
{
    public class ChartData
    {
        List<string> columns = new List<string>();
        List<string> rows = new List<string>();
        Dictionary<string, double> dataDictionary = new Dictionary<string, double>();
        List<Color> colors;

        public ChartData()
        {
            this.colors = new List<Color>
            {
                Color.FromRgb(83, 84, 138),
                Color.FromRgb(67, 128, 134),
                Color.FromRgb(160, 77, 163),
                Color.FromRgb(196, 101, 45),
                Color.FromRgb(139, 93, 61),
                Color.FromRgb(92, 146, 181)
            };
        }

        public string Title { get; set; }

        public Brush TitleBrush { get { return new SolidColorBrush(this.colors[5]); } }

        public IList<string> Columns { get { return this.columns; } }

        public IList<string> Rows { get { return this.rows; } }

        public int Range { get; set; }

        public string RangeFormatString { get; set; }

        public double GetValue(string row, string column)
        {
            string key = GetKey(row, column);

            return this.dataDictionary.ContainsKey(key) ? this.dataDictionary[key] : 0;
        }

        public void SetValue(string row, string column, double value)
        {
            string key = GetKey(row, column);

            if (!this.dataDictionary.ContainsKey(key))
                this.dataDictionary.Add(key, value);
            else
            {
                this.dataDictionary.Remove(key);
                this.dataDictionary.Add(key, value);
            }
        }

        internal IList<string> RangeLabels
        {
            get
            {
                var rangeLabels = new List<string>();

                for (int i = 3; i > 0; i--)
                {
                    int markerValue = i * this.Range / 4;

                    if (this.RangeFormatString != null)
                        rangeLabels.Add(markerValue.ToString(this.RangeFormatString));
                    else
                        rangeLabels.Add(markerValue.ToString());
                }
                
                return rangeLabels;
            }
        }

        internal Color GetRowColor(string row)
        {
            return this.colors[Math.Max(0, this.rows.IndexOf(row) % 5)];
        }

        internal IList<Brush> GetRowLabelBrushes()
        {
            var rowColors = new List<Brush>();

            foreach (string row in this.rows)
                rowColors.Add(new SolidColorBrush(this.GetRowColor(row)));

            return rowColors;
        }

        static string GetKey(string row, string column)
        {
            return Encode(row) + "|" + Encode(column);
        }

        static string Encode(string value)
        {
            byte[] bytes = Encoding.Default.GetBytes(value);
            return Convert.ToBase64String(bytes);
        }
    }
}
